package co.baiku.boot.common.tools;

import java.util.HashMap;
import java.util.Map;

public class ShortUrlTools {

    public static final char[] dictionary =
            {'q', 'g', '3', 'Q', '5', 'V', '8', 'G', 'n',
                    '1', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'p', 'a', 's', 'd',
                    'f', '2', 'h', 'j', 'k', 'z', 'x', 'c', 'v', 'b', '9', 'm',
                    'F', '4', 'W', 'E', 'R', 'T', 'Y', 'U', 'P', 'A', 'S', 'D',
                    'H', 'J', 'K', 'L', '6', 'Z', 'X', 'C', '7', 'B', 'N', 'M'};

    public static Map<Character, Integer> charValueMap = new HashMap<>();

    //初始化map
    static {
        for (int i = 0; i < dictionary.length; i++) {
            charValueMap.put(dictionary[i], i);
        }
    }

    private ShortUrlTools() {
    }

    /**
     * 把数字转换成相对应的进制,支持(2~${dictionary.length})进制
     *
     * @param dictionary 自定义字典
     * @param number     数字值
     * @param decimal    进制
     * @return 转换结果
     */
    public static String encode(char[] dictionary, long number, int decimal) {
        if (dictionary.length < decimal) {
            throw new IllegalArgumentException("The param 'decimal' must be not greater than " + dictionary.length);
        }
        StringBuilder builder = new StringBuilder();
        while (number != 0) {
            builder.append(dictionary[(int) (number - (number / decimal) * decimal)]);
            number /= decimal;
        }
        return builder.reverse().toString();
    }

    /**
     * 使用默认字典,把数字转换成相对应的进制,支持(2-${dictionary.length})进制
     *
     * @param number  数字值
     * @param decimal 进制
     * @return 转换结果
     */
    public static String encode(long number, int decimal) {
        return encode(dictionary, number, decimal);
    }

    /**
     * 把进制字符串转换成相应的数字值
     *
     * @param dictionary   自定义字典
     * @param encodeString 加密值
     * @param decimal      进制
     * @return 数字值
     */
    public static long decode(char[] dictionary, String encodeString, int decimal) {
        if (dictionary.length < decimal) {
            throw new IllegalArgumentException("The param 'decimal' must be not greater than " + dictionary.length);
        }
        long sum = 0;
        long multiple = 1;
        char[] chars = encodeString.toCharArray();
        for (int i = chars.length - 1; i >= 0; i--) {
            char c = chars[i];
            sum += charValueMap.get(c) * multiple;
            multiple *= decimal;
        }
        return sum;
    }

    /**
     * 把进制字符串转换成相应的数字值
     *
     * @param encodeString 加密值
     * @param decimal      进制
     * @return 数字值
     */
    public static long decode(String encodeString, int decimal) {
        return decode(dictionary, encodeString, decimal);
    }
}
